﻿using DDD.Domain;
using GoodsModule.Domain.GoodsDomainEvents;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace GoodsModule.Domain.GoodsAggregate
{
    // TODO: 回头想强类型主键
    public record GoodsId(int Id) : IKey<int>;

    [Comment("商品")]
    [Table("WbGoods")]
    public class Goods : Entity<int>, IAggregateRoot
    {

        public required int GoodsCategoryId { get; set; }

        #region 字段
        /// <summary>
        /// 标题
        /// </summary>
        [Comment("标题")]
        [Required]
        [StringLength(20)]
        public string Title { get; private set; } = string.Empty;
        /// <summary>
        /// 状态
        /// </summary>
        [Comment("状态")]
        [Required]
        [EnumDataType(typeof(GoodsStatus))]
        public GoodsStatus Status { get; private set; }

        /// <summary>
        /// 排序
        /// </summary>
        [Comment("排序")]
        [Required]
        public uint Sort { get; private set; } = 1000;

        /// <summary>
        /// 开始时间
        /// </summary>
        [Comment("开始时间")]
        [Required]
        [DataType(DataType.DateTime)]
        public DateTime StartTime { get; private set; } = DateTime.Now;

        /// <summary>
        /// 结束时间
        /// </summary>
        [Comment("结束时间")]
        [Required]
        [DataType(DataType.DateTime)]
        public DateTime EndTime { get; private set; } = DateTime.MaxValue;

        /// <summary>
        /// 库存
        /// </summary>
        [Comment("Stock")]
        [Required]
        public int Stock { get; private set; } = 0;

        /// <summary>
        /// 经验
        /// </summary>
        [Comment("经验")]
        [Required]
        [Precision(9, 2)]
        public decimal Exp { get; private set; } = 0;

        /// <summary>
        /// 积分
        /// </summary>
        [Comment("积分")]
        [Required]
        [Precision(9, 2)]
        public decimal Point { get; private set; } = 0;

        /// <summary>
        /// 金额
        /// </summary>
        [Comment("金额")]
        [Required]
        [Precision(9, 2)]
        public decimal Price { get; private set; } = 0;

        /// <summary>
        /// 内容
        /// </summary>
        [Comment("内容")]
        [Required]
        public string Content { get; private set; } = string.Empty;
        #endregion

        private Goods() { }

        public Goods(int goodsCategoryId, string title, GoodsStatus status, uint sort, DateTime startTime, DateTime endTime, int stock, decimal exp, decimal point, decimal price, string content, List<GoodsImage> imageList)
        {
            GoodsCategoryId = goodsCategoryId;
            Title = title;
            Status = status;
            Sort = sort;
            StartTime = startTime;
            EndTime = endTime;
            Stock = stock;
            Exp = exp;
            Point = point;
            Price = price;
            Content = content;
            ImageList = imageList;

            this.AddDomainEvent(new GoodsCreatedDomainEvent(this));
        }

        public List<GoodsImage> ImageList { get; private set; } = [];

        public void SetImages(GoodsImage item)
        {
            var _item = ImageList.FirstOrDefault(e => e.Id == item.Id);
            if (_item == null)
            {
                ImageList.Add(item);
            }
            else
            {
                _item.ChangeEntity(item);
            }
            //this.AddDomainEvent()
        }

        public bool CheckStock(int quantity)
        {
            if (Stock - quantity < 0)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 扣库存
        /// </summary>
        /// <param name="stock"></param>
        public bool CheckAndDeductStock(int quantity)
        {
            if (CheckStock(quantity) == false)
            {
                return false;
            }
            this.ChangeStock(Stock - quantity);
            return true;
        }

        /// <summary>
        /// 扣库存
        /// </summary>
        /// <param name="stock"></param>
        public bool DeductStock(int quantity)
        {
            if (Stock - quantity < 0)
            {
                return false;
            }
            this.ChangeStock(Stock - quantity);
            return true;
        }


        public void ChangePrice(decimal price)
        {
            Price = price;
            this.AddDomainEvent(new GoodsPriceChangedDomainEvent(this));
        }

        public void ChangePoint(decimal point)
        {
            Point = point;
            this.AddDomainEvent(new GoodsPointChangedDomainEvent(this));
        }

        public void ChangeExp(decimal exp)
        {
            Exp = exp;
            this.AddDomainEvent(new GoodsExpChangedDomainEvent(this));
        }

        public void ChangeStock(int stock)
        {
            Stock = stock;
            this.AddDomainEvent(new GoodsStockChangedDomainEvent(this));
        }

        public void ChangeStatus(GoodsStatus status)
        {
            Status = status;
            this.AddDomainEvent(new GoodsStatusChangedDomainEvent(this));
        }

        public void ChangeSort(uint sort)
        {
            Sort = sort;
            this.AddDomainEvent(new GoodsSortChangedDomainEvent(this));
        }

        public void ChangeTitle(string title)
        {
            Title = title;
            this.AddDomainEvent(new GoodsTitleChangedDomainEvent(this));
        }

        public void ChangeContent(string content)
        {
            Content = content;
            this.AddDomainEvent(new GoodsContentChangedDomainEvent(this));
        }

    }

}
